
class BaseServiceException(Exception):
    """服务层基础异常"""
    def __init__(self, message="业务处理异常", code=400, cause=None):
        self.code = code
        self.message = message
        self.cause = cause  # 原始异常
        super().__init__(f"[{code}] {message}")

    def __str__(self):
        if self.cause:
            return f"{super().__str__()} (Caused by: {str(self.cause)})"
        return super().__str__()

class InvalidOrderException(BaseServiceException):
    """订单数据非法异常"""
    def __init__(self, message="订单数据格式错误", code=400, invalid_fields=None):
        self.invalid_fields = invalid_fields or []
        super().__init__(
            message=f"{message} 无效字段: {self.invalid_fields}" if invalid_fields else message,
            code=code
        )

class InsufficientStockException(BaseServiceException):
    """库存不足异常"""
    def __init__(self, product_id, available, required, code=422):
        super().__init__(
            message=f"商品 {product_id} 库存不足 (可用: {available}, 需求: {required})",
            code=code
        )
        self.product_id = product_id
        self.available = available
        self.required = required

class ProductNotFoundException(BaseServiceException):
    """商品不存在异常"""
    def __init__(self, product_id, code=404):
        super().__init__(
            message=f"商品ID不存在: {product_id}",
            code=code
        )
        self.product_id = product_id

class RedisOperationException(BaseServiceException):
    """Redis操作异常"""
    def __init__(self, operation, key=None, code=503, cause=None):
        message = f"Redis操作失败: {operation}"
        if key:
            message += f" (key: {key})"
        super().__init__(
            message=message,
            code=code,
            cause=cause
        )
        self.operation = operation
        self.key = key

class ConcurrentUpdateException(BaseServiceException):
    """并发更新异常"""
    def __init__(self, resource_type, resource_id, code=409):
        super().__init__(
            message=f"{resource_type} {resource_id} 存在并发更新",
            code=code
        )
        self.resource_type = resource_type
        self.resource_id = resource_id
